package com.minotauro.i18n.scanner;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class Scanner {

  private IsTraversable isTraversable;
  private IsProcessable isProcessable;

  private Visitor visitor;

  // --------------------------------------------------------------------------------

  public Scanner( //
      IsTraversable isTraversable, IsProcessable isProcessable, Visitor visitor) {

    this.isTraversable = isTraversable;
    this.isProcessable = isProcessable;

    this.visitor = visitor;
  }

  // --------------------------------------------------------------------------------

  void setIsTraversable(IsTraversable isTraversable) {
    this.isTraversable = isTraversable;
  }

  // --------------------------------------------------------------------------------

  void setIsProcessable(IsProcessable isProcessable) {
    this.isProcessable = isProcessable;
  }

  // --------------------------------------------------------------------------------

  public void run(File root) {
    internalRun(root, new ArrayList<String>());
  }

  // --------------------------------------------------------------------------------

  private void internalRun(File root, List<String> path) {

    File[] files = root.listFiles();

    for (int i = 0; i < files.length; i++) {
      if (files[i].isDirectory()) {
        if (isTraversable(files[i], path)) {
          path.add(files[i].getName());
          internalRun(files[i], path);
          path.remove(path.size() - 1);
        }
      } else {
        if (isProcessable(files[i], path)) {
          visitor.visit(files[i], path);
        }
      }
    }
  }

  // --------------------------------------------------------------------------------

  private boolean isTraversable(File file, List<String> path) {
    return //
    isTraversable == null ? true : isTraversable.isTraversable(file, path);
  }

  // --------------------------------------------------------------------------------

  private boolean isProcessable(File file, List<String> path) {
    return //
    isProcessable == null ? true : isProcessable.isProcessable(file, path);
  }

  // --------------------------------------------------------------------------------

}
